#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
IR 访问表达式节点定义
"""

from dataclasses import dataclass, field
from typing import Iterator, Optional
import ast
from .base import IRExpr, build_expr_from_ast
from ..base import IRNode, get_default_ir_node


@dataclass
class IRAttribute(IRExpr):
    """属性访问节点"""

    value: IRNode = field(default_factory=get_default_ir_node)
    attr: str = field(default="")
    node_type: str = "attribute"

    def get_child_nodes(self) -> Iterator[IRNode]:
        """获取所有子节点"""
        if self.value and hasattr(self.value, "node_type"):
            yield self.value
        yield from super().get_child_nodes()

    def build_from_ast(self, node: ast.Attribute) -> None:
        """从 AST 属性节点构建 IR 属性节点内容

        Args:
            node: AST 属性节点
        """
        super().build_from_ast(node)

        self.attr = node.attr
        self.value = build_expr_from_ast(node.value, self)


@dataclass
class IRSlice(IRExpr):
    """切片节点，表示 lower:upper:step"""

    lower: Optional[IRNode] = field(default=None)
    upper: Optional[IRNode] = field(default=None)
    step: Optional[IRNode] = field(default=None)
    node_type: str = "slice"

    def get_child_nodes(self) -> Iterator[IRNode]:
        """获取所有子节点"""
        if self.lower is not None:
            yield self.lower
        if self.upper is not None:
            yield self.upper
        if self.step is not None:
            yield self.step
        yield from super().get_child_nodes()

    def build_from_ast(self, node: ast.Slice) -> None:
        """从 AST 切片节点构建 IR 切片节点内容"""
        super().build_from_ast(node)

        if node.lower is not None:
            self.lower = build_expr_from_ast(node.lower, self)
        if node.upper is not None:
            self.upper = build_expr_from_ast(node.upper, self)
        if node.step is not None:
            self.step = build_expr_from_ast(node.step, self)


@dataclass
class IRSubscript(IRExpr):
    """下标访问节点"""

    value: IRNode = field(default_factory=get_default_ir_node)
    slice: IRNode = field(default_factory=get_default_ir_node)
    node_type: str = "subscript"

    def get_child_nodes(self) -> Iterator[IRNode]:
        """获取所有子节点"""
        yield self.value
        yield self.slice
        yield from super().get_child_nodes()

    def build_from_ast(self, node: ast.Subscript) -> None:
        """从 AST 下标节点构建 IR 下标节点内容

        Args:
            node: AST 下标节点
        """
        super().build_from_ast(node)

        # 构建被下标的值
        self.value = build_expr_from_ast(node.value, self)

        # 构建下标表达式
        self.slice = build_expr_from_ast(node.slice, self)
